home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MyRegisterPort.c
-
- Contains: Contains the custom routines for registering an offlineing an OT Port
- See the PortScanner.c file for an explanation of the call
-
- Written by:
-
- Copyright: Copyright © 1998-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 8/16/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
-
-
- #pragma export on
-
- //----------------------------------------------------------------------
-
- #define DEBUG 1
- //----------------------------------------------------------------------
-
- #include <OpenTptModule.h>
- #include <OpenTptLinks.h>
- #include <PCCardEnablerPlugin.h>
- #include <PCCardTuples.h>
- #include <Gestalt.h>
- #include <DriverFamilyMatching.h>
- #include "EnablerSample.h"
- #include "MyRegisterPort.h"
-
-
- static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum);
- static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef);
-
- /*
- The OfflinePortExists call is used to offline a port
- where the assumption is that the deviceRef for the device
- in the NameRegistry is stored in the fContext field of the
- portRecord. This routine searches the ports for an entry which
- has a matching deviceRef value and unregisters the port.
-
- Assumes that there is an existing port that has as it's fContext
- value, the same as *deviceRef, so that the value can be matched.
- */
-
- static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum)
- {
- DriverServiceInfo *dsi;
- TPortRecord *portRecord;
- UInt32 index;
- UInt32 busType;
- size_t idx;
- OSStatus err;
- Boolean foundOne;
-
-
- #if DEBUG
- DebugStr("\p about to check for offlined ports");
- #endif
-
- index = 0;
- while (portRecord = OTGetIndexedPort(index))
- {
- index++;
-
- busType = OTGetBusTypeFromPortRef(portRecord->fRef);
- if (busType == kOTPCCardBus)
- {
- #if DEBUG
- DebugStr("\p PCCard port found");
- #endif
-
- // check if the socket numbers match
- if (((UInt8)portRecord->fSlotID[0] - '0') != socketNum)
- {
- #if DEBUG
- DebugStr("\p socketNum - no match");
- #endif
- continue;
- }
- #if DEBUG
- DebugStr("\p socketNum - matches");
- #endif
-
- // check if the port is offlined
- if (portRecord->fPortFlags && kOTPortIsOffline)
- {
- // we've found an offline port.
- // check if the driver descriptor info matches the info in the port
- dsi = dd->driverServices.service;
-
- foundOne = false;
-
- for (idx = 0; idx < dd->driverServices.nServices; ++idx)
- {
- if ( dsi->serviceCategory == kServiceCategoryOpenTransport )
- {
- foundOne = true;
- break;
- }
- dsi += 1;
- }
-
- if (foundOne == true)
- {
- // check if the driver name matches
- if (OTMemcmp(&(dd->driverOSRuntimeInfo.driverName[1]), portRecord->fModuleName,
- dd->driverOSRuntimeInfo.driverName[0]) == true)
- {
- #if DEBUG
- DebugStr("\p matching offline port found");
- #endif
- // restore the fPortFlags
- portRecord->fPortFlags &= ~(kOTPortIsOffline + kOTPortIsUnavailable );
-
- // set the fContext field to the current deviceRef
- *(RegEntryID *)portRecord->fContext = *deviceRef;
- err = SetPortConfiguredProperty(deviceRef);
- if (err)
- {
- #if DEBUG
- DebugStr("\p RegistryPropertySet for port-configured property failed");
- #endif
- }
- return true;
- }
- }
- }
- }
- }
- #if DEBUG
- DebugStr("\p matching offliner port not found");
- #endif
-
- return false;
-
- }
-
- /*
- The OfflineThePort call is used to offline a port
- where the assumption is that the deviceRef for the device
- in the NameRegistry is stored in the fContext field of the
- portRecord. This routine searches the ports for an entry which
- has a matching deviceRef value and unregisters the port.
-
- Assumes that there is an existing port that has as it's fContext
- value, the same as *deviceRef, so that the value can be matched.
- */
- extern void OfflineThePort(RegEntryID *deviceRef)
- {
- RegEntryID *portContext;
- TPortRecord *portRecord;
- UInt32 index;
- UInt32 busType;
-
-
- #if DEBUG
- DebugStr("\p about to check bus");
- #endif
-
- index = 0;
- while (portRecord = OTGetIndexedPort(index))
- {
- index++;
- busType = OTGetBusTypeFromPortRef(portRecord->fRef);
- if (busType == kOTPCCardBus)
- {
- // check if the deviceRef matches
- portContext = portRecord->fContext;
- if (*((long*)deviceRef) == *((long*)portContext))
- {
- // set the offline bit in the fPortFlags field
- portRecord->fPortFlags |= kOTPortIsOffline;
- portRecord->fPortFlags |= kOTPortIsUnavailable;
- #if DEBUG
- DebugStr("\p port offlined");
- #endif
- return;
- }
- }
- }
- #if DEBUG
- DebugStr("\p port not found to offline");
- #endif
- }
-
- /*
- The RegisterThePort call is used to register a network port for a
- PC Card 3.0 device with Open Transport. The call
- is designed for alternate networking cards like TokenRing, and ATM
- which are not handled by the default PC Card Port Scanner.
-
- This function checks for the presence of a
- "driver-descriptor" and the "SocketNumber" property associated with
- the device node. It uses the these properties to fill in the port information.
-
- The call looks at the "driver-descriptor" property to know how to fill out the
- TPortRecord structure.
-
- */
- void RegisterThePort( RegEntryID *deviceRef)
- {
- char buffer[sizeof(DriverDescription) +
- kMaxServices*sizeof(DriverServiceInfo)];
- DriverDescription *dd = (DriverDescription*)buffer;
- DriverServiceInfo *dsi;
- OTPortRecord *portRecord;
- RegEntryID *portContext;
- OSStatus err;
- UInt32 size;
- UInt32 framing;
- UInt32 socket;
- size_t idx;
- size_t sIndex = 0;
- UInt16 other;
- UInt16 otType;
- UInt16 iface;
- Boolean foundOne;
-
- #if DEBUG
- DebugStr("\p port scanner: RegisterThePort");
- #endif
-
- //
- // If the driver has no driver-descriptor property, or the size
- // is too small, or it is too large to fit our buffer - forget
- // this one.
- //
- err = RegistryPropertyGetSize(deviceRef, kDescriptorProperty, &size);
- if ( err != noErr || size < sizeof(DriverDescription) ||
- size > sizeof(buffer) )
- {
- #if DEBUG
- DebugStr("\p kPropertyDriverDesc not found");
- #endif
- return;
- }
-
- //
- // Read the driver-descriptor property into our buffer.
- //
- err = RegistryPropertyGet(deviceRef, kDescriptorProperty, buffer, &size);
-
- if ( err != noErr )
- {
- #if DEBUG
- DebugStr("\p kPropertyDriverDesc not found");
- #endif
- return;
- }
-
- //
- // Read the SocketNumber property into our buffer.
- //
- size = sizeof(socket);
- err = RegistryPropertyGet(deviceRef, kSocketNumber, &socket, &size);
-
- if ( err != noErr )
- {
- #if DEBUG
- DebugStr("\p socket property not found");
- #endif
- return;
- }
-
- //
- // Check whether an offline port exists for this module
- //
-
- if (OfflinePortExists(deviceRef, dd, socket) == true)
- {
- return;
- }
-
- dsi = dd->driverServices.service;
- foundOne = false;
-
- for (idx = 0; idx < dd->driverServices.nServices; ++idx)
- {
- if ( dsi->serviceCategory == kServiceCategoryOpenTransport )
- {
- foundOne = true;
- break;
- }
- dsi += 1;
- }
-
- if (foundOne == false)
- return;
-
- // check if there is a driver name
- if (dd->driverOSRuntimeInfo.driverName[0] == 0 )
- return;
-
- // lets register this port - first get some memory
- portRecord = (OTPortRecord*)OTAllocPortMem(sizeof(OTPortRecord));
- if (portRecord == nil)
- return;
-
- OTMemzero(portRecord, sizeof(OTPortRecord));
-
- OTMemcpy(&portRecord->fModuleName, &dd->driverOSRuntimeInfo.driverName[1],
- dd->driverOSRuntimeInfo.driverName[0]);
-
- otType = (UInt16)((dsi->serviceType >> 16) & 0x7ff);
- iface = (UInt16)(dsi->serviceType & 3);
- framing = (UInt32)((dsi->serviceType >> 8) & 0xff);
-
- // find a unique "other" value for this device
- other = 0;
- do
- {
- portRecord->fRef = OTCreatePortRef(kOTPCCardBus, otType, socket, other++);
- } while ( OTFindPortByRef(portRecord->fRef) != 0 );
-
- // now set the associated slot
- // portRecord->fSlotID[0] = 0;
-
- OTMemcpy(&portRecord->fSlotID, " \0", 2);
- portRecord->fSlotID[0] = (char)('0'+ socket);
-
- // for the fInfoFlag the 0x1 indicates the module is DLPI
- // for a TPI interface, set the value to 0x2
-
- portRecord->fInfoFlags = iface;
- portRecord->fCapabilities = framing;
- portRecord->fNumChildPorts = 0;
- portRecord->fPortName[0] = 0;
-
- // allocate port context memory
- portContext = (RegEntryID*)OTAllocPortMem(sizeof(RegEntryID));
- if (portContext != nil)
- {
- // store the deviceRef in the portContext field so that
- // we can discriminate this port entry later when we for a matching
- // port to offline.
- *portContext = *deviceRef;
-
- #if DEBUG
- DebugStr("\p about to register port");
- #endif
- err = OTRegisterPort(portRecord, (void*)portContext);
-
- if (err == noErr)
- {
- err = SetPortConfiguredProperty(deviceRef);
- if (err)
- {
- #if DEBUG
- DebugStr("\p RegistryPropertySet for port-configured property failed");
- #endif
- }
- }
- else
- {
- #if DEBUG
- DebugStr("\p OTRegisterPort failed");
- #endif
- }
- }
- else
- {
- #if DEBUG
- DebugStr("\p OTAllocPortMem failed");
- #endif
- OTFreePortMem(portRecord);
- }
- }
-
- static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef)
- {
- OSStatus err;
- UInt16 portConfigProperty = 1;
-
- // modify the port-configured property to indicate that we have registered the
- // port. Note that the presence of this property tells the default PC Card
- // Port scanner that the port has been previously registered, whatever the
- // value. This scanner checks the value and if zero, registers the port.
- // then we set the value to 1 to indicate that we've registered it. Later
- // we might find this port and have a way to know that we've already configured
- // this device.
- err = RegistryPropertySet(deviceRef, kPortConfigured,
- &portConfigProperty, sizeof(portConfigProperty));
- return err;
- }
-
- #pragma export off